package com.hb.G_协程.D_使用同步的方式写异步代码

import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import java.util.concurrent.TimeUnit

/**
 * 利用协程来优雅的处理异步逻辑
 */
fun main() = runBlocking{
    val start = System.currentTimeMillis()

    //耗时2s
    /**
     * 在我们执行这两个查询操作的时候，在协程内部，这两个方法其实是顺序执行的，也就是说
     * 先执行searchItemOne(),再执行searchItemTwo()
     */
//    val searchItemOne = searchItemOne()
//    val searchItemTwo = searchItemTwo()
//    println("the item is ${searchItemOne} and ${searchItemTwo}")

    /**
     *
     * 顺序执行是不合理的，因为这两个查询的操作不会相互依赖，也就是说，第二个查询操作不需要等第一个查询
     * 操作完成之后再去执行，他们的关系应该是并行的。
     *
     * 将两个查询操作利用async包裹了起来，类似于launch,使用async也相当于创建了一个子协程，他会和其他协程
     * 一样并行执行。与launch不同的是，async会返回一个Deferred对象。Deferred值是一个非阻塞可取消的future
     * 他是一个带有结果的job。future的意思是将来会返回一个结果，利用await方法可以等待这个值查询到之后，然后将
     * 他获取出来。
     */
    val searchItemOne = async { searchItemOne() }
    val searchItemTwo = async {searchItemTwo() }

    println("the item is ${searchItemOne.await()} and ${searchItemTwo.await()}")

    val end = System.currentTimeMillis()
    val toSeconds = TimeUnit.MILLISECONDS.toSeconds(end - start)

    println("耗时： $toSeconds s")
}

suspend fun searchItemOne():String{
    delay(1000)
    return "item one"
}

suspend fun searchItemTwo():String{
    delay(1000)
    return "item two"
}